package com.woniuxy.pxxt.shiro;


import com.woniuxy.pxxt.dto.menu.MenuDto;
import com.woniuxy.pxxt.dto.menu.MenuListDto;
import com.woniuxy.pxxt.entity.Menu;
import com.woniuxy.pxxt.entity.Role;
import com.woniuxy.pxxt.entity.User;
import com.woniuxy.pxxt.service.MenuService;
import com.woniuxy.pxxt.service.RoleService;
import com.woniuxy.pxxt.utils.JWTUtil;
import com.woniuxy.pxxt.utils.TokenUtil;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * @Author: ideaAdmin
 * TODO: Class
 * TODO: 自定义域
 * Date: 2022/2/23:17:41
 * Description:
 */
@Component
public class MyRealm extends AuthorizingRealm {


    @Autowired
   private  RedisTemplate redisTemplate;

    @Autowired
    private RoleService roleService;

    @Autowired
    private MenuService menuService;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        String token = principals.getPrimaryPrincipal()+ "";

//        String username = JWTUtil.getUsername(token);
        //根据用户获取它的所有角色
        User user = (User) redisTemplate.opsForValue().get(TokenUtil.getUser().getToken());

        List<Role> roles =user.getRoles();


        List<MenuDto> menus = user.getMenuDtos() == null ? new ArrayList<MenuDto>() :user.getMenuDtos();
        if(roles == null || roles.size() <= 0){
            roles = roleService.findRoleByAccount(user);

            roles.forEach(role->{
                //根据角色获得它的菜单权限
                MenuListDto menuListDto = (MenuListDto)menuService.findMenuByRoleId(role.getId()).getData();
                menus.addAll((menuListDto.getMenuDtos()) );
            });
            user.setMenuDtos(menus);
            redisTemplate.opsForValue().set(user.getToken(),user);
        }
        //角色
        Set<String> userRoles = new HashSet<>();

        //菜单权限
        Set<String> userMenus = new HashSet<>();

        for (Role rbacRole:roles){
            userRoles.add(rbacRole.getRole());
        }


        for(MenuDto menu:menus){
            userMenus.add(menu.getLabel());
        }

        //把角色和权限set到AuthorizationInfo(授权信息)中 并返回 使用注解来判断
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.setRoles(userRoles);
        simpleAuthorizationInfo.setStringPermissions(userMenus);
        return simpleAuthorizationInfo;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //转为自定义JWT
        MyJsonWebToken jsonWebToken = (MyJsonWebToken) authenticationToken;

        String token = jsonWebToken.getToken();

        //使用token获得存放的对象
        User user = (User) redisTemplate.opsForValue().get(token);

        if(user != null){
            return new SimpleAuthenticationInfo(user, token, "myRealm");
        }else {
            throw new AuthenticationException("token失效了");
        }
    }
}
